package com.staryy.activiti7_workflow.controller;


import com.staryy.activiti7_workflow.SecurityUtil;
import com.staryy.activiti7_workflow.pojo.UserInfoBean;
import com.staryy.activiti7_workflow.util.AjaxResponse;
import com.staryy.activiti7_workflow.util.GlobalConfig;
import org.activiti.api.model.shared.model.VariableInstance;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.GetVariablesPayloadBuilder;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 流程实例接口
 */
@RestController
@RequestMapping("/processInstance")
public class ProcessInstanceController {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private SecurityUtil securityUtil;

    @Autowired
    private ProcessRuntime processRuntime;

    /**
     * 获取流程实例列表
     *
     * @return
     */
    @GetMapping("/getInstances")
    public AjaxResponse getInstances(@AuthenticationPrincipal UserInfoBean userInfoBean) {
        try {
            if(GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            List<Map<String,Object>> mapList = new ArrayList<>();
            Page<ProcessInstance> instancePage = processRuntime.processInstances(Pageable.of(0, 100));
            List<ProcessInstance> content = instancePage.getContent();
            content.sort((y,x) -> x.getStatus().toString().compareTo(y.getStartDate().toString()));
            for(ProcessInstance instance : content){
                Map<String,Object> map = new HashMap<>();
                map.put("id",instance.getId());
                map.put("name",instance.getName());
                map.put("status",instance.getStatus());
                map.put("processDefinitionId",instance.getProcessDefinitionId());
                map.put("processDefinitionKey",instance.getProcessDefinitionKey());
                map.put("processDefinitionVersion",instance.getProcessDefinitionVersion());
                map.put("startDate",instance.getStartDate());

                ProcessDefinition definition = repositoryService.createProcessDefinitionQuery()
                        .processDefinitionId(instance.getProcessDefinitionId()).singleResult();

                map.put("resourceName",definition.getResourceName());
                map.put("deploymentId",definition.getDeploymentId());
                mapList.add(map);
            }
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),GlobalConfig.ResponseCode.SUCCESS.getDesc(),mapList);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(),GlobalConfig.ResponseCode.ERRPR.getDesc(),null);
        }
    }

    /**
     * 启动流程实例
     * @return
     */
    @GetMapping("/startProcess")
    public AjaxResponse startProcess(@RequestParam("processDefinitionKey") String processDefinitionKey,
                                     @RequestParam("instanceName") String instanceName) {
        try {
            if(GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }

//            else{
//                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
//            }
            ProcessInstance processInstance = processRuntime.start(
                    ProcessPayloadBuilder.start()
                            .withProcessDefinitionKey(processDefinitionKey)
                            .withName(instanceName)
                            .build());
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),GlobalConfig.ResponseCode.SUCCESS.getDesc(),processInstance.getId());
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(),"启动流程实例失败",e.toString());
        }
    }

    /**
     * 删除流程实例
     * @return
     */
    @GetMapping("/delInstance")
    public AjaxResponse startProcess(@RequestParam("instanceId") String instanceId) {
        try {
            if(GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            ProcessInstance processInstance = processRuntime.delete(
                    ProcessPayloadBuilder.delete()
                            .withProcessInstanceId(instanceId)
                            .build());
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),GlobalConfig.ResponseCode.SUCCESS.getDesc(),processInstance.getId());
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(),"删除流程实例失败",e.toString());
        }
    }

    /**
     * 挂起流程实例
     * @return
     */
    @GetMapping("/suspendInstance")
    public AjaxResponse suspendInstance(@RequestParam("instanceId") String instanceId) {
        try {
            if(GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            ProcessInstance processInstance = processRuntime.suspend(
                    ProcessPayloadBuilder.suspend()
                            .withProcessInstanceId(instanceId)
                            .build());
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),GlobalConfig.ResponseCode.SUCCESS.getDesc(),processInstance.getStatus());
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(),"挂起流程实例失败",e.toString());
        }
    }

    /**
     * 激活流程实例
     * @return
     */
    @GetMapping("/resumeInstance")
    public AjaxResponse resumeInstance(@RequestParam("instanceId") String instanceId) {
        try {
            if(GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            ProcessInstance processInstance = processRuntime.resume(
                    ProcessPayloadBuilder.resume()
                            .withProcessInstanceId(instanceId)
                            .build());
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),GlobalConfig.ResponseCode.SUCCESS.getDesc(),processInstance.getStatus());
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(),"激活流程实例失败",e.toString());
        }
    }


    /**
     * 获取流程参数
     * @return
     */
    @GetMapping("/getVariables")
    public AjaxResponse getVariables(@RequestParam("instanceId") String instanceId) {
        try {
            if(GlobalConfig.Test) {
                securityUtil.logInAs("bajie");
            }
            List<VariableInstance> variables = processRuntime.variables(ProcessPayloadBuilder.variables()
                    .withProcessInstanceId(instanceId)
                    .build());
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),GlobalConfig.ResponseCode.SUCCESS.getDesc(),variables);
        } catch (Exception e) {
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERRPR.getCode(),"查询实例参数失败",e.toString());
        }
    }
}
